package com.ruoyi.web.utils;


import org.apache.logging.log4j.util.Strings;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author gong_da_kai
 * @version 1.0.0
 * @since 2021/11/20 11:07 上午
 */
public class ReflectUtil {
    /**
     * get
     */
    public static final String GET = "get";
    /**
     * set
     */
    public static final String SET = "set";

    /**
     * 循环向上转型, 获取fieldName对应的Getter
     * 如向上转型到Object仍无法找到, 返回null
     *
     * @param obj       对象
     * @param fieldName 属性名
     * @return {@link Method}
     * @author gong_da_kai
     * @since 2021/11/20
     */
    public static Method getGetter(final Object obj, final String fieldName) {
        // 为空不报错。直接返回 null
        if (obj == null) {
            return null;
        }

        if (Strings.isBlank(fieldName)) {
            throw new RuntimeException("fieldName can't be blank");
        }

        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredMethod(getGetterStr(fieldName));
            } catch (NoSuchMethodException ignored) {
            }
        }

        return null;
    }

    /**
     * 循环向上转型, 获取fieldName对应的Setter
     * 如向上转型到Object仍无法找到, 返回null
     *
     * @param obj       对象
     * @param fieldName 属性名
     * @param filedType 属性类型
     * @return {@link Method}
     * @author gong_da_kai
     * @since 2021/11/20
     */
    public static Method getSetter(final Object obj, final String fieldName, final Class<?> filedType) {
        // 为空不报错。直接返回 null
        if (obj == null) {
            return null;
        }

        if (Strings.isBlank(fieldName)) {
            throw new RuntimeException("fieldName can't be blank");
        }

        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredMethod(getSetterStr(fieldName), filedType);
            } catch (NoSuchMethodException ignored) {
            }
        }

        return null;
    }

    /**
     * 根据属性名获得getter
     *
     * @param fieldName 属性名
     * @return {@link String}
     * @author gong_da_kai
     * @since 2021/11/20
     */
    public static String getGetterStr(final String fieldName) {
        return ReflectUtil.GET + firstLetter2Uppercase(fieldName);
    }

    /**
     * 根据属性名获得setter
     *
     * @param fieldName 属性名
     * @return {@link String}
     * @author gong_da_kai
     * @since 2021/11/20
     */
    public static String getSetterStr(final String fieldName) {
        return ReflectUtil.SET + firstLetter2Uppercase(fieldName);
    }

    /**
     * 设置字符串的第一个字母为大写
     *
     * @param str 字符串
     * @return {@link String}
     * @author gong_da_kai
     * @since 2021/11/20
     */
    public static String firstLetter2Uppercase(String str) {
        if (Strings.isBlank(str)) {
            return str;
        }

        String firstLetter = String.valueOf(str.charAt(0));

        return str.replaceFirst(firstLetter, firstLetter.toUpperCase());
    }

    /**
     * 获取类及其所有父类（不含Object）的属性
     *
     * @param type 类
     * @return {@link List< Field>}
     * @author gong_da_kai
     * @since 2021/12/22
     */
    public static List<Field> getFiledAsList(Class<?> type) {
        List<Field> fieldList = new ArrayList<>();
        for (; Object.class != type; type = type.getSuperclass()) {
            fieldList.addAll(Arrays.asList(type.getDeclaredFields()));
        }

        return fieldList;
    }
}
